home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / dev / gcc / gcc270_src.lha / gcc-2.7.0-amiga / config / spur / spur.md < prev    next >
Text File  |  1995-06-15  |  32KB  |  1,094 lines

  1. ;;- Machine description for SPUR chip for GNU C compiler
  2. ;;   Copyright (C) 1988 Free Software Foundation, Inc.
  3.  
  4. ;; This file is part of GNU CC.
  5.  
  6. ;; GNU CC is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation; either version 2, or (at your option)
  9. ;; any later version.
  10.  
  11. ;; GNU CC is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;; GNU General Public License for more details.
  15.  
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU CC; see the file COPYING.  If not, write to
  18. ;; the Free Software Foundation, 59 Temple Place - Suite 330,
  19. ;; Boston, MA 02111-1307, USA.
  20.  
  21.  
  22. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  23.  
  24. ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
  25. ;;- updates for most instructions.
  26.  
  27. ;;- Operand classes for the register allocator:
  28.  
  29. ;; Compare instructions.
  30. ;; This pattern is used for generating an "insn"
  31. ;; which does just a compare and sets a (fictitious) condition code.
  32.  
  33. ;; The actual SPUR insns are compare-and-conditional-jump.
  34. ;; The define_peephole's below recognize the combinations of
  35. ;; compares and jumps, and output each pair as a single assembler insn.
  36.  
  37. ;; This controls RTL generation and register allocation.
  38. (define_insn "cmpsi"
  39.   [(set (cc0)
  40.     (compare (match_operand:SI 0 "register_operand" "rK")
  41.          (match_operand:SI 1 "nonmemory_operand" "rK")))]
  42.   ""
  43.   "*
  44. {
  45.   cc_status.value1 = operands[0], cc_status.value2 = operands[1];
  46.   return \"\";
  47. }")
  48.  
  49. ;; We have to have this because cse can optimize the previous pattern
  50. ;; into this one.
  51.  
  52. (define_insn "tstsi"
  53.   [(set (cc0)
  54.     (match_operand:SI 0 "register_operand" "r"))]
  55.   ""
  56.   "*
  57. {
  58.   cc_status.value1 = operands[0], cc_status.value2 = const0_rtx;
  59.   return \"\";
  60. }")
  61.  
  62.  
  63. ;; These control RTL generation for conditional jump insns
  64. ;; and match them for register allocation.
  65.  
  66. (define_insn "beq"
  67.   [(set (pc)
  68.     (if_then_else (eq (cc0)
  69.               (const_int 0))
  70.               (label_ref (match_operand 0 "" ""))
  71.               (pc)))]
  72.   ""
  73.   "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
  74.  
  75. (define_insn "bne"
  76.   [(set (pc)
  77.     (if_then_else (ne (cc0)
  78.               (const_int 0))
  79.               (label_ref (match_operand 0 "" ""))
  80.               (pc)))]
  81.   ""
  82.   "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
  83.  
  84. (define_insn "bgt"
  85.   [(set (pc)
  86.     (if_then_else (gt (cc0)
  87.               (const_int 0))
  88.               (label_ref (match_operand 0 "" ""))
  89.               (pc)))]
  90.   ""
  91.   "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
  92.  
  93. (define_insn "bgtu"
  94.   [(set (pc)
  95.     (if_then_else (gtu (cc0)
  96.                (const_int 0))
  97.               (label_ref (match_operand 0 "" ""))
  98.               (pc)))]
  99.   ""
  100.   "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
  101.  
  102. (define_insn "blt"
  103.   [(set (pc)
  104.     (if_then_else (lt (cc0)
  105.               (const_int 0))
  106.               (label_ref (match_operand 0 "" ""))
  107.               (pc)))]
  108.   ""
  109.   "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
  110.  
  111. (define_insn "bltu"
  112.   [(set (pc)
  113.     (if_then_else (ltu (cc0)
  114.                (const_int 0))
  115.               (label_ref (match_operand 0 "" ""))
  116.               (pc)))]
  117.   ""
  118.   "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
  119.  
  120. (define_insn "bge"
  121.   [(set (pc)
  122.     (if_then_else (ge (cc0)
  123.               (const_int 0))
  124.               (label_ref (match_operand 0 "" ""))
  125.               (pc)))]
  126.   ""
  127.   "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
  128.  
  129. (define_insn "bgeu"
  130.   [(set (pc)
  131.     (if_then_else (geu (cc0)
  132.                (const_int 0))
  133.               (label_ref (match_operand 0 "" ""))
  134.               (pc)))]
  135.   ""
  136.   "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
  137.  
  138. (define_insn "ble"
  139.   [(set (pc)
  140.     (if_then_else (le (cc0)
  141.               (const_int 0))
  142.               (label_ref (match_operand 0 "" ""))
  143.               (pc)))]
  144.   ""
  145.   "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
  146.  
  147. (define_insn "bleu"
  148.   [(set (pc)
  149.     (if_then_else (leu (cc0)
  150.                (const_int 0))
  151.               (label_ref (match_operand 0 "" ""))
  152.               (pc)))]
  153.   ""
  154.   "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
  155.  
  156. ;; These match inverted jump insns for register allocation.
  157.  
  158. (define_insn ""
  159.   [(set (pc)
  160.     (if_then_else (eq (cc0)
  161.               (const_int 0))
  162.               (pc)
  163.               (label_ref (match_operand 0 "" ""))))]
  164.   ""
  165.   "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
  166.  
  167. (define_insn ""
  168.   [(set (pc)
  169.     (if_then_else (ne (cc0)
  170.               (const_int 0))
  171.               (pc)
  172.               (label_ref (match_operand 0 "" ""))))]
  173.   ""
  174.   "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
  175.  
  176. (define_insn ""
  177.   [(set (pc)
  178.     (if_then_else (gt (cc0)
  179.               (const_int 0))
  180.               (pc)
  181.               (label_ref (match_operand 0 "" ""))))]
  182.   ""
  183.   "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
  184.  
  185. (define_insn ""
  186.   [(set (pc)
  187.     (if_then_else (gtu (cc0)
  188.                (const_int 0))
  189.               (pc)
  190.               (label_ref (match_operand 0 "" ""))))]
  191.   ""
  192.   "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
  193.  
  194. (define_insn ""
  195.   [(set (pc)
  196.     (if_then_else (lt (cc0)
  197.               (const_int 0))
  198.               (pc)
  199.               (label_ref (match_operand 0 "" ""))))]
  200.   ""
  201.   "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
  202.  
  203. (define_insn ""
  204.   [(set (pc)
  205.     (if_then_else (ltu (cc0)
  206.                (const_int 0))
  207.               (pc)
  208.               (label_ref (match_operand 0 "" ""))))]
  209.   ""
  210.   "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
  211.  
  212. (define_insn ""
  213.   [(set (pc)
  214.     (if_then_else (ge (cc0)
  215.               (const_int 0))
  216.               (pc)
  217.               (label_ref (match_operand 0 "" ""))))]
  218.   ""
  219.   "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
  220.  
  221. (define_insn ""
  222.   [(set (pc)
  223.     (if_then_else (geu (cc0)
  224.                (const_int 0))
  225.               (pc)
  226.               (label_ref (match_operand 0 "" ""))))]
  227.   ""
  228.   "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
  229.  
  230. (define_insn ""
  231.   [(set (pc)
  232.     (if_then_else (le (cc0)
  233.               (const_int 0))
  234.               (pc)
  235.               (label_ref (match_operand 0 "" ""))))]
  236.   ""
  237.   "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
  238.  
  239. (define_insn ""
  240.   [(set (pc)
  241.     (if_then_else (leu (cc0)
  242.                (const_int 0))
  243.               (pc)
  244.               (label_ref (match_operand 0 "" ""))))]
  245.   ""
  246.   "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
  247.  
  248. ;; Move instructions
  249.  
  250. (define_insn "movsi"
  251.   [(set (match_operand:SI 0 "general_operand" "=r,m")
  252.     (match_operand:SI 1 "general_operand" "rmi,rJ"))]
  253.   ""
  254.   "*
  255. {
  256.   if (GET_CODE (operands[0]) == MEM)
  257.     return \"st_32 %r1,%0\";
  258.   if (GET_CODE (operands[1]) == MEM)
  259.     return \"ld_32 %0,%1\;nop\";
  260.   if (GET_CODE (operands[1]) == REG)
  261.     return \"add_nt %0,%1,$0\";
  262.   if (GET_CODE (operands[1]) == SYMBOL_REF && operands[1]->unchanging)
  263.     return \"add_nt %0,r24,$(%1-0b)\";
  264.   return \"add_nt %0,r0,%1\";
  265. }")
  266.  
  267. (define_insn ""
  268.   [(set (match_operand:SI 0 "register_operand" "=r")
  269.     (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
  270.              (match_operand:SI 2 "register_operand" "r"))))]
  271.   ""
  272.   "ld_32 %0,%1,%2\;nop")
  273.  
  274. ;; Generate insns for moving single bytes.
  275.  
  276. (define_expand "movqi"
  277.   [(set (match_operand:QI 0 "general_operand" "")
  278.     (match_operand:QI 1 "general_operand" ""))]
  279.   ""
  280.   "
  281. {
  282.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  283.     operands[1] = copy_to_reg (operands[1]);
  284.  
  285.   if (GET_CODE (operands[1]) == MEM)
  286.     {
  287.       rtx tem = gen_reg_rtx (SImode);
  288.       rtx addr = force_reg (SImode, XEXP (operands[1], 0));
  289.       rtx subreg;
  290.  
  291.       emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
  292.       if (GET_CODE (operands[0]) == SUBREG)
  293.     subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[0]),
  294.               SUBREG_WORD (operands[0]));
  295.       else
  296.     subreg = gen_rtx (SUBREG, SImode, operands[0], 0);
  297.  
  298.       emit_insn (gen_rtx (SET, VOIDmode, subreg,
  299.               gen_rtx (ZERO_EXTRACT, SImode, tem,
  300.                    gen_rtx (CONST_INT, VOIDmode, 8),
  301.                    addr)));
  302.     }
  303.   else if (GET_CODE (operands[0]) == MEM)
  304.     {
  305.       rtx tem = gen_reg_rtx (SImode);
  306.       rtx addr = force_reg (SImode, XEXP (operands[0], 0));
  307.       rtx subreg;
  308.  
  309.       emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
  310.       if (! CONSTANT_ADDRESS_P (operands[1]))
  311.     {
  312.       if (GET_CODE (operands[1]) == SUBREG)
  313.         subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
  314.                   SUBREG_WORD (operands[1]));
  315.       else
  316.         subreg = gen_rtx (SUBREG, SImode, operands[1], 0);
  317.     }
  318.  
  319.       emit_insn (gen_rtx (SET, VOIDmode,
  320.               gen_rtx (ZERO_EXTRACT, SImode, tem,
  321.                    gen_rtx (CONST_INT, VOIDmode, 8),
  322.                    addr),
  323.               subreg));
  324.       emit_move_insn (gen_rtx (MEM, SImode, addr), tem);
  325.     }
  326.   else
  327.     {
  328.       emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
  329.     }
  330.   DONE;
  331. }")
  332.  
  333. ;; Recognize insns generated for moving single bytes.
  334.  
  335. (define_insn ""
  336.   [(set (match_operand:QI 0 "general_operand" "=r,m")
  337.     (match_operand:QI 1 "general_operand" "rmi,r"))]
  338.   ""
  339.   "*
  340. {
  341.   if (GET_CODE (operands[0]) == MEM)
  342.     return \"st_32 %1,%0\";
  343.   if (GET_CODE (operands[1]) == MEM)
  344.     return \"ld_32 %0,%1\;nop\";
  345.   if (GET_CODE (operands[1]) == REG)
  346.     return \"add_nt %0,%1,$0\";
  347.   return \"add_nt %0,r0,%1\";
  348. }")
  349.  
  350. (define_insn ""
  351.   [(set (match_operand:SI 0 "register_operand" "=r")
  352.     (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  353.              (const_int 8)
  354.              (match_operand:SI 2 "nonmemory_operand" "rI")))]
  355.   ""
  356.   "extract %0,%1,%2")
  357.  
  358. (define_insn ""
  359.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
  360.              (const_int 8)
  361.              (match_operand:SI 1 "nonmemory_operand" "rI"))
  362.     (match_operand:SI 2 "nonmemory_operand" "ri"))]
  363.   ""
  364.   "wr_insert %1\;insert %0,%0,%2")
  365.  
  366. ;; Constant propagation can optimize the previous pattern into this pattern.
  367. ;[Not any more.  It could when the position-operand contains a MULT.]
  368.  
  369. ;(define_insn ""
  370. ;  [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r")
  371. ;             (const_int 8)
  372. ;             (match_operand:SI 1 "immediate_operand" "I"))
  373. ;    (match_operand:QI 2 "register_operand" "r"))]
  374. ;  "GET_CODE (operands[1]) == CONST_INT
  375. ;   && INTVAL (operands[1]) % 8 == 0
  376. ;   && (unsigned) INTVAL (operands[1]) < 32"
  377. ;  "*
  378. ;{
  379. ;  operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
  380. ;  return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
  381. ;}")
  382.  
  383. ;; The three define_expand patterns on this page
  384. ;; serve as subroutines of "movhi".
  385.  
  386. ;; Generate code to fetch an aligned halfword from memory.
  387. ;; Operand 0 is the destination register (HImode).
  388. ;; Operand 1 is the memory address (SImode).
  389. ;; Operand 2 is a temporary (SImode).
  390. ;; Operand 3 is a temporary (SImode).
  391. ;; Operand 4 is a temporary (QImode).
  392.  
  393. ;; Operand 5 is an internal temporary (HImode).
  394.  
  395. (define_expand "loadhi"
  396.   [(set (match_operand:SI 2 "register_operand" "")
  397.     (mem:SI (match_operand:SI 1 "register_operand" "")))
  398.    ;; Extract the low byte.
  399.    (set (subreg:SI (match_dup 5) 0)
  400.     (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1)))
  401.    ;; Form address of high byte.
  402.    (set (match_operand:SI 3 "register_operand" "")
  403.     (plus:SI (match_dup 1) (const_int 1)))
  404.    ;; Extract the high byte.
  405.    (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
  406.     (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)))
  407.    ;; Put the high byte in with the low one.
  408.    (set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1))
  409.     (subreg:SI (match_dup 4) 0))
  410.    (set (match_operand:HI 0 "register_operand" "") (match_dup 5))]
  411.   ""
  412.   "operands[5] = gen_reg_rtx (HImode);")
  413.  
  414. ;; Generate code to store an aligned halfword into memory.
  415. ;; Operand 0 is the destination address (SImode).
  416. ;; Operand 1 is the source register (HImode, not constant).
  417. ;; Operand 2 is a temporary (SImode).
  418. ;; Operand 3 is a temporary (SImode).
  419. ;; Operand 4 is a temporary (QImode).
  420.  
  421. ;; Operand 5 is an internal variable made from operand 1.
  422.  
  423. (define_expand "storehi"
  424.   [(set (match_operand:SI 2 "register_operand" "")
  425.     (mem:SI (match_operand:SI 0 "register_operand" "")))
  426.    ;; Insert the low byte.
  427.    (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
  428.     (match_dup 5))
  429.    ;; Form address of high byte.
  430.    (set (match_operand:SI 3 "register_operand" "")
  431.     (plus:SI (match_dup 0) (const_int 1)))
  432.    ;; Extract the high byte from the source.
  433.    (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
  434.     (zero_extract:SI (match_operand:HI 1 "register_operand" "")
  435.              (const_int 8) (const_int 1)))
  436.    ;; Store high byte into the memory word
  437.    (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
  438.     (subreg:SI (match_dup 4) 0))
  439.    ;; Put memory word back into memory.
  440.    (set (mem:SI (match_dup 0))
  441.     (match_dup 2))]
  442.   ""
  443.   "
  444. {
  445.   if (GET_CODE (operands[1]) == SUBREG)
  446.     operands[5] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
  447.                SUBREG_WORD (operands[1]));
  448.   else
  449.     operands[5] = gen_rtx (SUBREG, SImode, operands[1], 0);
  450. }")
  451.  
  452. ;; Like storehi but operands[1] is a CONST_INT.
  453.  
  454. (define_expand "storeinthi"
  455.   [(set (match_operand:SI 2 "register_operand" "")
  456.     (mem:SI (match_operand:SI 0 "register_operand" "")))
  457.    ;; Insert the low byte.
  458.    (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
  459.     (match_dup 5))
  460.    ;; Form address of high byte.
  461.    (set (match_operand:SI 3 "register_operand" "")
  462.     (plus:SI (match_dup 0) (const_int 1)))
  463.    ;; Store high byte into the memory word
  464.    (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
  465.     (match_dup 6))
  466.    ;; Put memory word back into memory.
  467.    (set (mem:SI (match_dup 0))
  468.     (match_dup 2))]
  469.   ""
  470.   " operands[5] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 255);
  471.     operands[6] = gen_rtx (CONST_INT, VOIDmode,
  472.                (INTVAL (operands[1]) >> 8) & 255);
  473. ")
  474.  
  475. ;; Main entry for generating insns to move halfwords.
  476.  
  477. (define_expand "movhi"
  478.   [(set (match_operand:HI 0 "general_operand" "")
  479.     (match_operand:HI 1 "general_operand" ""))]
  480.   ""
  481.   "
  482. {
  483.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  484.     operands[1] = copy_to_reg (operands[1]);
  485.   
  486.   if (GET_CODE (operands[1]) == MEM)
  487.     {
  488.       rtx insn =
  489.     emit_insn (gen_loadhi (operands[0],
  490.                    force_reg (SImode, XEXP (operands[1], 0)),
  491.                    gen_reg_rtx (SImode), gen_reg_rtx (SImode),
  492.                    gen_reg_rtx (QImode)));
  493.       /* Tell cse what value the loadhi produces, so it detect duplicates.  */
  494.       REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1],
  495.                          REG_NOTES (insn));
  496.     }
  497.   else if (GET_CODE (operands[0]) == MEM)
  498.     {
  499.       if (GET_CODE (operands[1]) == CONST_INT)
  500.     emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands[0], 0)),
  501.                        operands[1],
  502.                    gen_reg_rtx (SImode), gen_reg_rtx (SImode),
  503.                    gen_reg_rtx (QImode)));
  504.       else
  505.     {
  506.       if (CONSTANT_P (operands[1]))
  507.             operands[1] = force_reg (HImode, operands[1]);
  508.       emit_insn (gen_storehi (force_reg (SImode, XEXP (operands[0], 0)),
  509.                   operands[1],
  510.                   gen_reg_rtx (SImode), gen_reg_rtx (SImode),
  511.                   gen_reg_rtx (QImode)));
  512.     }
  513.     }
  514.   else
  515.     emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
  516.   DONE;
  517. }")
  518.  
  519. ;; Recognize insns generated for moving halfwords.
  520. ;; (Note that the extract and insert patterns for single-byte moves
  521. ;;  are also involved in recognizing some of the insns used for this purpose.)
  522.  
  523. (define_insn ""
  524.   [(set (match_operand:HI 0 "general_operand" "=r,m")
  525.     (match_operand:HI 1 "general_operand" "rmi,r"))]
  526.   ""
  527.   "*
  528. {
  529.   if (GET_CODE (operands[0]) == MEM)
  530.     return \"st_32 %1,%0\";
  531.   if (GET_CODE (operands[1]) == MEM)
  532.     return \"ld_32 %0,%1\;nop\";
  533.   if (GET_CODE (operands[1]) == REG)
  534.     return \"add_nt %0,%1,$0\";
  535.   return \"add_nt %0,r0,%1\";
  536. }")
  537.  
  538. (define_insn ""
  539.   [(set (match_operand:SI 0 "register_operand" "=r")
  540.     (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
  541.              (const_int 8)
  542.              (match_operand:SI 2 "nonmemory_operand" "rI")))]
  543.   ""
  544.   "extract %0,%1,%2")
  545.  
  546. (define_insn ""
  547.   [(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r")
  548.              (const_int 8)
  549.              (match_operand:SI 1 "nonmemory_operand" "rI"))
  550.     (match_operand:SI 2 "nonmemory_operand" "ri"))]
  551.   ""
  552.   "wr_insert %1\;insert %0,%0,%2")
  553.  
  554. ;; Constant propagation can optimize the previous pattern into this pattern.
  555.  
  556. ;(define_insn ""
  557. ;  [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r")
  558. ;             (const_int 8)
  559. ;             (match_operand:SI 1 "immediate_operand" "I"))
  560. ;    (match_operand:QI 2 "register_operand" "r"))]
  561. ;  "GET_CODE (operands[1]) == CONST_INT
  562. ;   && INTVAL (operands[1]) % 8 == 0
  563. ;   && (unsigned) INTVAL (operands[1]) < 32"
  564. ;  "*
  565. ;{
  566. ;  operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
  567. ;  return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
  568. ;}")
  569.  
  570. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  571. ;; to be reloaded by putting the constant into memory.
  572. ;; It must come before the more general movdf pattern.
  573. (define_insn ""
  574.   [(set (match_operand:DF 0 "general_operand" "=&r,f,&o")
  575.     (match_operand:DF 1 "" "mG,m,G"))]
  576.   "GET_CODE (operands[1]) == CONST_DOUBLE"
  577.   "*
  578. {
  579.   if (FP_REG_P (operands[0]))
  580.     return output_fp_move_double (operands);
  581.   if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == REG)
  582.     {
  583.       operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  584.       return \"add_nt %0,r0,$0\;add_nt %1,r0,$0\";
  585.     }
  586.   if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == MEM)
  587.     {
  588.       operands[1] = adj_offsettable_operand (operands[0], 4);
  589.       return \"st_32 r0,%0\;st_32 r0,%1\";
  590.     }
  591.   return output_move_double (operands);
  592. }
  593. ")
  594.   
  595. (define_insn "movdf"
  596.   [(set (match_operand:DF 0 "general_operand" "=r,&r,m,?f,?rm")
  597.     (match_operand:DF 1 "general_operand" "r,m,r,rfm,f"))]
  598.   ""
  599.   "*
  600. {
  601.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  602.     return output_fp_move_double (operands);
  603.   return output_move_double (operands);
  604. }
  605. ")
  606.  
  607. (define_insn "movdi"
  608.   [(set (match_operand:DI 0 "general_operand" "=r,&r,m,?f,?rm")
  609.     (match_operand:DI 1 "general_operand" "r,m,r,rfm,f"))]
  610.   ""
  611.   "*
  612. {
  613.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  614.     return output_fp_move_double (operands);
  615.   return output_move_double (operands);
  616. }
  617. ")
  618.  
  619. (define_insn "movsf"
  620.   [(set (match_operand:SF 0 "general_operand" "=rf,m")
  621.     (match_operand:SF 1 "general_operand" "rfm,rf"))]
  622.   ""
  623.   "*
  624. {
  625.   if (FP_REG_P (operands[0]))
  626.     {
  627.       if (FP_REG_P (operands[1]))
  628.     return \"fmov %0,%1\";
  629.       if (GET_CODE (operands[1]) == REG)
  630.     {
  631.       rtx xoperands[2];
  632.       int offset = - get_frame_size () - 8;
  633.       xoperands[1] = operands[1];
  634.       xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
  635.       output_asm_insn (\"st_32 %1,r25,%0\", xoperands);
  636.       xoperands[1] = operands[0];
  637.       output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands);
  638.       return \"\";
  639.     }
  640.       return \"ld_sgl %0,%1\;nop\";
  641.     }
  642.   if (FP_REG_P (operands[1]))
  643.     {
  644.       if (GET_CODE (operands[0]) == REG)
  645.     {
  646.       rtx xoperands[2];
  647.       int offset = - get_frame_size () - 8;
  648.       xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
  649.       xoperands[1] = operands[1];
  650.       output_asm_insn (\"st_sgl %1,r25,%0\", xoperands);
  651.       xoperands[1] = operands[0];
  652.       output_asm_insn (\"ld_32 %1,r25,%0\;nop\", xoperands);
  653.       return \"\";
  654.     }
  655.       return \"st_sgl %1,%0\";
  656.     }
  657.   if (GET_CODE (operands[0]) == MEM)
  658.     return \"st_32 %r1,%0\";
  659.   if (GET_CODE (operands[1]) == MEM)
  660.     return \"ld_32 %0,%1\;nop\";
  661.   if (GET_CODE (operands[1]) == REG)
  662.     return \"add_nt %0,%1,$0\";
  663.   return \"add_nt %0,r0,%1\";
  664. }")
  665.  
  666. ;;- truncation instructions
  667. (define_insn "truncsiqi2"
  668.   [(set (match_operand:QI 0 "register_operand" "=r")
  669.     (truncate:QI
  670.      (match_operand:SI 1 "register_operand" "r")))]
  671.   ""
  672.   "add_nt %0,%1,$0")
  673.  
  674. (define_insn "trunchiqi2"
  675.   [(set (match_operand:QI 0 "register_operand" "=r")
  676.     (truncate:QI
  677.      (match_operand:HI 1 "register_operand" "r")))]
  678.   ""
  679.   "add_nt %0,%1,$0")
  680.  
  681. (define_insn "truncsihi2"
  682.   [(set (match_operand:HI 0 "register_operand" "=r")
  683.     (truncate:HI
  684.      (match_operand:SI 1 "register_operand" "r")))]
  685.   ""
  686.   "add_nt %0,%1,$0")
  687.  
  688. ;;- zero extension instructions
  689.  
  690. ;; Note that the one starting from HImode comes before those for QImode
  691. ;; so that a constant operand will match HImode, not QImode.
  692. (define_expand "zero_extendhisi2"
  693.   [(set (match_operand:SI 0 "register_operand" "")
  694.     (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
  695.         ;; This constant is invalid, but reloading will handle it.
  696.         ;; It's useless to generate here the insns to construct it
  697.         ;; because constant propagation would simplify them anyway.
  698.         (match_dup 2)))]
  699.   ""
  700.   "
  701. {
  702.   if (GET_CODE (operands[1]) == SUBREG)
  703.     operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
  704.                SUBREG_WORD (operands[1]));
  705.   else
  706.     operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
  707.  
  708.   operands[2] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
  709. }")
  710.  
  711. (define_insn "zero_extendqihi2"
  712.   [(set (match_operand:HI 0 "register_operand" "=r")
  713.     (zero_extend:HI
  714.      (match_operand:QI 1 "register_operand" "r")))]
  715.   ""
  716.   "extract %0,%1,$0")
  717.  
  718. (define_insn "zero_extendqisi2"
  719.   [(set (match_operand:SI 0 "register_operand" "=r")
  720.     (zero_extend:SI
  721.      (match_operand:QI 1 "register_operand" "r")))]
  722.   ""
  723.   "extract %0,%1,$0")
  724.  
  725. ;;- sign extension instructions
  726. ;; Note that the one starting from HImode comes before those for QImode
  727. ;; so that a constant operand will match HImode, not QImode.
  728.  
  729. (define_expand "extendhisi2"
  730.   [(set (match_dup 2)
  731.     (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
  732.         (match_dup 4)))
  733.    (set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5)))
  734.    (set (match_operand:SI 0 "register_operand" "")
  735.     (xor:SI (match_dup 3) (match_dup 5)))]
  736.   ""
  737.   "
  738. {
  739.   if (GET_CODE (operands[1]) == SUBREG)
  740.     operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
  741.                SUBREG_WORD (operands[1]));
  742.   else
  743.     operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
  744.  
  745.   operands[2] = gen_reg_rtx (SImode);
  746.   operands[3] = gen_reg_rtx (SImode);
  747.   operands[4] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
  748.   operands[5] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768));
  749. }")
  750.  
  751. (define_expand "extendqihi2"
  752.   [(set (match_dup 2)
  753.     (and:HI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
  754.         (const_int 255)))
  755.    (set (match_dup 3)
  756.     (plus:SI (match_dup 2) (const_int -128)))
  757.    (set (match_operand:HI 0 "register_operand" "")
  758.     (xor:SI (match_dup 3) (const_int -128)))]
  759.   ""
  760.   "
  761. {
  762.   if (GET_CODE (operands[1]) == SUBREG)
  763.     operands[1] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[1]),
  764.                SUBREG_WORD (operands[1]));
  765.   else
  766.     operands[1] = gen_rtx (SUBREG, HImode, operands[1], 0);
  767.  
  768.   operands[2] = gen_reg_rtx (HImode);
  769.   operands[3] = gen_reg_rtx (HImode);
  770. }")
  771.  
  772. (define_expand "extendqisi2"
  773.   [(set (match_dup 2)
  774.     (and:SI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
  775.         (const_int 255)))
  776.    (set (match_dup 3) (plus:SI (match_dup 2) (const_int -128)))
  777.    (set (match_operand:SI 0 "register_operand" "")
  778.     (xor:SI (match_dup 3) (const_int -128)))]
  779.   ""
  780.   "
  781. {
  782.   if (GET_CODE (operands[1]) == SUBREG)
  783.     operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
  784.                SUBREG_WORD (operands[1]));
  785.   else
  786.     operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
  787.  
  788.   operands[2] = gen_reg_rtx (SImode);
  789.   operands[3] = gen_reg_rtx (SImode);
  790. }")
  791.  
  792. ;;- arithmetic instructions
  793.  
  794. (define_insn "addsi3"
  795.   [(set (match_operand:SI 0 "register_operand" "=r")
  796.     (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
  797.          (match_operand:SI 2 "nonmemory_operand" "rI")))]
  798.   ""
  799.   "add %0,%1,%2")
  800.  
  801. (define_insn ""
  802.   [(set (match_operand:SI 0 "register_operand" "=r")
  803.     (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
  804.          (match_operand:SI 2 "big_immediate_operand" "g")))]
  805.   "GET_CODE (operands[2]) == CONST_INT 
  806.    && (unsigned) (INTVAL (operands[2]) + 0x8000000) < 0x10000000"
  807.   "*
  808. {
  809.   return 
  810.     output_add_large_offset (operands[0], operands[1], INTVAL (operands[2]));
  811. }")
  812.  
  813. (define_insn "subsi3"
  814.   [(set (match_operand:SI 0 "register_operand" "=r")
  815.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  816.           (match_operand:SI 2 "nonmemory_operand" "rI")))]
  817.   ""
  818.   "sub %0,%1,%2")
  819.  
  820. (define_insn "andsi3"
  821.   [(set (match_operand:SI 0 "register_operand" "=r")
  822.     (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
  823.         (match_operand:SI 2 "nonmemory_operand" "rI")))]
  824.   ""
  825.   "and %0,%1,%2")
  826.  
  827. (define_insn "iorsi3"
  828.   [(set (match_operand:SI 0 "register_operand" "=r")
  829.     (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
  830.         (match_operand:SI 2 "nonmemory_operand" "rI")))]
  831.   ""
  832.   "or %0,%1,%2")
  833.  
  834. (define_insn "xorsi3"
  835.   [(set (match_operand:SI 0 "register_operand" "=r")
  836.     (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
  837.         (match_operand:SI 2 "nonmemory_operand" "rI")))]
  838.   ""
  839.   "xor %0,%1,%2")
  840.  
  841. (define_insn "negsi2"
  842.   [(set (match_operand:SI 0 "register_operand" "=r")
  843.     (neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))]
  844.   ""
  845.   "sub %0,r0,%1")
  846.  
  847. (define_insn "one_cmplsi2"
  848.   [(set (match_operand:SI 0 "register_operand" "=r")
  849.     (not:SI (match_operand:SI 1 "register_operand" "r")))]
  850.   ""
  851.   "xor %0,%1,$-1")
  852.  
  853. ;; Floating point arithmetic instructions.
  854.  
  855. (define_insn "adddf3"
  856.   [(set (match_operand:DF 0 "register_operand" "=f")
  857.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  858.          (match_operand:DF 2 "register_operand" "f")))]
  859.   "TARGET_FPU"
  860.   "fadd %0,%1,%2")
  861.  
  862. (define_insn "addsf3"
  863.   [(set (match_operand:SF 0 "register_operand" "=f")
  864.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  865.          (match_operand:SF 2 "register_operand" "f")))]
  866.   "TARGET_FPU"
  867.   "fadd %0,%1,%2")
  868.  
  869. (define_insn "subdf3"
  870.   [(set (match_operand:DF 0 "register_operand" "=f")
  871.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  872.           (match_operand:DF 2 "register_operand" "f")))]
  873.   "TARGET_FPU"
  874.   "fsub %0,%1,%2")
  875.  
  876. (define_insn "subsf3"
  877.   [(set (match_operand:SF 0 "register_operand" "=f")
  878.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  879.           (match_operand:SF 2 "register_operand" "f")))]
  880.   "TARGET_FPU"
  881.   "fsub %0,%1,%2")
  882.  
  883. (define_insn "muldf3"
  884.   [(set (match_operand:DF 0 "register_operand" "=f")
  885.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  886.          (match_operand:DF 2 "register_operand" "f")))]
  887.   "TARGET_FPU"
  888.   "fmul %0,%1,%2")
  889.  
  890. (define_insn "mulsf3"
  891.   [(set (match_operand:SF 0 "register_operand" "=f")
  892.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  893.          (match_operand:SF 2 "register_operand" "f")))]
  894.   "TARGET_FPU"
  895.   "fmul %0,%1,%2")
  896.  
  897. (define_insn "divdf3"
  898.   [(set (match_operand:DF 0 "register_operand" "=f")
  899.     (div:DF (match_operand:DF 1 "register_operand" "f")
  900.         (match_operand:DF 2 "register_operand" "f")))]
  901.   "TARGET_FPU"
  902.   "fdiv %0,%1,%2")
  903.  
  904. (define_insn "divsf3"
  905.   [(set (match_operand:SF 0 "register_operand" "=f")
  906.     (div:SF (match_operand:SF 1 "register_operand" "f")
  907.         (match_operand:SF 2 "register_operand" "f")))]
  908.   "TARGET_FPU"
  909.   "fdiv %0,%1,%2")
  910.  
  911. (define_insn "negdf2"
  912.   [(set (match_operand:DF 0 "register_operand" "=f")
  913.     (neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
  914.   "TARGET_FPU"
  915.   "fneg %0,%1")
  916.  
  917. (define_insn "negsf2"
  918.   [(set (match_operand:SF 0 "register_operand" "=f")
  919.     (neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
  920.   "TARGET_FPU"
  921.   "fneg %0,%1")
  922.  
  923. (define_insn "absdf2"
  924.   [(set (match_operand:DF 0 "register_operand" "=f")
  925.     (abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
  926.   "TARGET_FPU"
  927.   "fabs %0,%1")
  928.  
  929. (define_insn "abssf2"
  930.   [(set (match_operand:SF 0 "register_operand" "=f")
  931.     (abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
  932.   "TARGET_FPU"
  933.   "fabs %0,%1")
  934.  
  935. ;; Shift instructions
  936.  
  937. (define_insn ""
  938.   [(set (match_operand:SI 0 "register_operand" "=r")
  939.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  940.            (match_operand:SI 2 "immediate_operand" "I")))]
  941.   "GET_CODE (operands[2]) == CONST_INT"
  942.   "*
  943. {
  944.   unsigned int amount = INTVAL (operands[2]);
  945.  
  946.   switch (amount)
  947.     {
  948.     case 0:
  949.       return \"add_nt %0,%1,$0\";
  950.     case 1:
  951.       return \"sll %0,%1,$1\";
  952.     case 2:
  953.       return \"sll %0,%1,$2\";
  954.     default:
  955.       output_asm_insn (\"sll %0,%1,$3\", operands);
  956.  
  957.       for (amount -= 3; amount >= 3; amount -= 3)
  958.     output_asm_insn (\"sll %0,%0,$3\", operands);
  959.  
  960.       if (amount > 0)
  961.     output_asm_insn (amount == 1 ? \"sll %0,%0,$1\" : \"sll %0,%0,$2\",
  962.              operands);
  963.       return \"\";
  964.     }
  965. }")
  966.  
  967. (define_insn ""
  968.   [(set (match_operand:SI 0 "register_operand" "=r")
  969.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  970.                  (match_operand:SI 2 "immediate_operand" "I")))]
  971.   "GET_CODE (operands[2]) == CONST_INT"
  972.   "*
  973. {
  974.   unsigned int amount = INTVAL (operands[2]);
  975.  
  976.   if (amount == 0) 
  977.     return \"add_nt %0,%1,$0\";
  978.   else
  979.     output_asm_insn (\"sra %0,%1,$1\", operands);
  980.   
  981.   for (amount -= 1; amount > 0; amount -= 1)
  982.     output_asm_insn (\"sra %0,%0,$1\", operands);
  983.  
  984.   return \"\";
  985. }")
  986.  
  987. (define_insn ""
  988.   [(set (match_operand:SI 0 "register_operand" "=r")
  989.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  990.                  (match_operand:SI 2 "immediate_operand" "I")))]
  991.   "GET_CODE (operands[2]) == CONST_INT"
  992.   "*
  993. {
  994.   unsigned int amount = INTVAL (operands[2]);
  995.  
  996.   if (amount == 0) 
  997.     return \"add_nt %0,%1,$0\";
  998.   else
  999.     output_asm_insn (\"srl %0,%1,$1\", operands);
  1000.   
  1001.   for (amount -= 1; amount > 0; amount -= 1)
  1002.     output_asm_insn (\"srl %0,%0,$1\", operands);
  1003.  
  1004.   return \"\";
  1005. }")
  1006.  
  1007. (define_expand "ashlsi3"
  1008.   [(set (match_operand:SI 0 "register_operand" "")
  1009.     (ashift:SI (match_operand:SI 1 "register_operand" "")
  1010.            (match_operand:SI 2 "nonmemory_operand" "")))]
  1011.   ""
  1012.   "
  1013. {
  1014.   if (GET_CODE (operands[2]) != CONST_INT
  1015.       || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 3))
  1016.     FAIL;
  1017. }")
  1018.  
  1019. (define_expand "ashrsi3"
  1020.   [(set (match_operand:SI 0 "register_operand" "")
  1021.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
  1022.              (match_operand:SI 2 "nonmemory_operand" "")))]
  1023.   ""
  1024.   "
  1025. {
  1026.   if (GET_CODE (operands[2]) != CONST_INT
  1027.       || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
  1028.     FAIL;
  1029. }")
  1030.  
  1031. (define_expand "lshrsi3"
  1032.   [(set (match_operand:SI 0 "register_operand" "")
  1033.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
  1034.              (match_operand:SI 2 "nonmemory_operand" "")))]
  1035.   ""
  1036.   "
  1037. {
  1038.   if (GET_CODE (operands[2]) != CONST_INT
  1039.       || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
  1040.     FAIL;
  1041. }")
  1042.  
  1043. ;; Unconditional and other jump instructions
  1044. (define_insn "jump"
  1045.   [(set (pc)
  1046.     (label_ref (match_operand 0 "" "")))]
  1047.   ""
  1048.   "jump %l0\;nop")
  1049.  
  1050. (define_insn "tablejump"
  1051.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  1052.    (use (label_ref (match_operand 1 "" "")))]
  1053.   ""
  1054.   "jump_reg r0,%0\;nop")
  1055.  
  1056. ;;- jump to subroutine
  1057. (define_insn "call"
  1058.   [(call (match_operand:SI 0 "memory_operand" "m")
  1059.      (match_operand:SI 1 "general_operand" "g"))]
  1060.   ;;- Don't use operand 1 for most machines.
  1061.   ""
  1062.   "add_nt r2,%0\;call .+8\;jump_reg r0,r2\;nop")
  1063.  
  1064. (define_insn "call_value"
  1065.   [(set (match_operand 0 "" "=g")
  1066.     (call (match_operand:SI 1 "memory_operand" "m")
  1067.           (match_operand:SI 2 "general_operand" "g")))]
  1068.   ;;- Don't use operand 1 for most machines.
  1069.   ""
  1070.   "add_nt r2,%1\;call .+8\;jump_reg r0,r2\;nop")
  1071.  
  1072. ;; A memory ref with constant address is not normally valid.
  1073. ;; But it is valid in a call insns.  This pattern allows the
  1074. ;; loading of the address to combine with the call.
  1075. (define_insn ""
  1076.   [(call (mem:SI (match_operand:SI 0 "" "i"))
  1077.      (match_operand:SI 1 "general_operand" "g"))]
  1078.   ;;- Don't use operand 1 for most machines.
  1079.   "GET_CODE (operands[0]) == SYMBOL_REF"
  1080.   "call %0\;nop")
  1081.  
  1082. (define_insn ""
  1083.   [(set (match_operand 0 "" "=g")
  1084.     (call (mem:SI (match_operand:SI 1 "" "i"))
  1085.           (match_operand:SI 2 "general_operand" "g")))]
  1086.   ;;- Don't use operand 1 for most machines.
  1087.   "GET_CODE (operands[1]) == SYMBOL_REF"
  1088.   "call %1\;nop")
  1089.  
  1090. (define_insn "nop"
  1091.   [(const_int 0)]
  1092.   ""
  1093.   "nop")
  1094.